home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / balsente.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  11KB  |  471 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw/balsente.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ****************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #ifndef INCLUDE_DRAW_CORE
  13.  
  14. /*************************************
  15.  *
  16.  *    External globals
  17.  *
  18.  *************************************/
  19.  
  20. extern UINT8 balsente_shooter;
  21. extern UINT8 balsente_shooter_x;
  22. extern UINT8 balsente_shooter_y;
  23.  
  24.  
  25.  
  26. /*************************************
  27.  *
  28.  *    Statics
  29.  *
  30.  *************************************/
  31.  
  32. static UINT8 *local_videoram;
  33. static UINT8 *scanline_dirty;
  34. static UINT8 *scanline_palette;
  35.  
  36. static UINT8 last_scanline_palette;
  37. static UINT8 screen_refresh_counter;
  38. static UINT8 palettebank_vis;
  39.  
  40.  
  41.  
  42. /*************************************
  43.  *
  44.  *    Prototypes
  45.  *
  46.  *************************************/
  47.  
  48. void balsente_vh_stop(void);
  49.  
  50. static void update_screen_8(struct osd_bitmap *bitmap, int full_refresh);
  51. static void update_screen_16(struct osd_bitmap *bitmap, int full_refresh);
  52.  
  53.  
  54. /*************************************
  55.  *
  56.  *    Video system start
  57.  *
  58.  *************************************/
  59.  
  60. int balsente_vh_start(void)
  61. {
  62.     /* reset the system */
  63.     palettebank_vis = 0;
  64.  
  65.     /* allocate a local copy of video RAM */
  66.     local_videoram = malloc(256 * 256);
  67.     if (!local_videoram)
  68.     {
  69.         balsente_vh_stop();
  70.         return 1;
  71.     }
  72.  
  73.     /* allocate a scanline dirty array */
  74.     scanline_dirty = malloc(256);
  75.     if (!scanline_dirty)
  76.     {
  77.         balsente_vh_stop();
  78.         return 1;
  79.     }
  80.  
  81.     /* allocate a scanline palette array */
  82.     scanline_palette = malloc(256);
  83.     if (!scanline_palette)
  84.     {
  85.         balsente_vh_stop();
  86.         return 1;
  87.     }
  88.  
  89.     /* mark everything dirty to start */
  90.     memset(scanline_dirty, 1, 256);
  91.  
  92.     /* reset the scanline palette */
  93.     memset(scanline_palette, 0, 256);
  94.     last_scanline_palette = 0;
  95.  
  96.     return 0;
  97. }
  98.  
  99.  
  100.  
  101. /*************************************
  102.  *
  103.  *    Video system shutdown
  104.  *
  105.  *************************************/
  106.  
  107. void balsente_vh_stop(void)
  108. {
  109.     /* free the local video RAM array */
  110.     if (local_videoram)
  111.         free(local_videoram);
  112.     local_videoram = NULL;
  113.  
  114.     /* free the scanline dirty array */
  115.     if (scanline_dirty)
  116.         free(scanline_dirty);
  117.     scanline_dirty = NULL;
  118.  
  119.     /* free the scanline dirty array */
  120.     if (scanline_palette)
  121.         free(scanline_palette);
  122.     scanline_palette = NULL;
  123. }
  124.  
  125.  
  126.  
  127. /*************************************
  128.  *
  129.  *    Video RAM write
  130.  *
  131.  *************************************/
  132.  
  133. WRITE_HANDLER( balsente_videoram_w )
  134. {
  135.     videoram[offset] = data;
  136.  
  137.     /* expand the two pixel values into two bytes */
  138.     local_videoram[offset * 2 + 0] = data >> 4;
  139.     local_videoram[offset * 2 + 1] = data & 15;
  140.  
  141.     /* mark the scanline dirty */
  142.     scanline_dirty[offset / 128] = 1;
  143. }
  144.  
  145.  
  146.  
  147. /*************************************
  148.  *
  149.  *    Palette banking
  150.  *
  151.  *************************************/
  152.  
  153. static void update_palette(void)
  154. {
  155.     int scanline = cpu_getscanline(), i;
  156.     if (scanline > 255) scanline = 0;
  157.  
  158.     /* special case: the scanline is the same as last time, but a screen refresh has occurred */
  159.     if (scanline == last_scanline_palette && screen_refresh_counter)
  160.     {
  161.         for (i = 0; i < 256; i++)
  162.         {
  163.             /* mark the scanline dirty if it was a different palette */
  164.             if (scanline_palette[i] != palettebank_vis)
  165.                 scanline_dirty[i] = 1;
  166.             scanline_palette[i] = palettebank_vis;
  167.         }
  168.     }
  169.  
  170.     /* fill in the scanlines up till now */
  171.     else
  172.     {
  173.         for (i = last_scanline_palette; i != scanline; i = (i + 1) & 255)
  174.         {
  175.             /* mark the scanline dirty if it was a different palette */
  176.             if (scanline_palette[i] != palettebank_vis)
  177.                 scanline_dirty[i] = 1;
  178.             scanline_palette[i] = palettebank_vis;
  179.         }
  180.  
  181.         /* remember where we left off */
  182.         last_scanline_palette = scanline;
  183.     }
  184.  
  185.     /* reset the screen refresh counter */
  186.     screen_refresh_counter = 0;
  187. }
  188.  
  189.  
  190. WRITE_HANDLER( balsente_palette_select_w )
  191. {
  192.     /* only update if changed */
  193.     if (palettebank_vis != (data & 3))
  194.     {
  195.         /* update the scanline palette */
  196.         update_palette();
  197.         palettebank_vis = data & 3;
  198.     }
  199.  
  200.     logerror("balsente_palette_select_w(%d) scanline=%d\n", data & 3, cpu_getscanline());
  201. }
  202.  
  203.  
  204.  
  205. /*************************************
  206.  *
  207.  *    Palette RAM write
  208.  *
  209.  *************************************/
  210.  
  211. WRITE_HANDLER( balsente_paletteram_w )
  212. {
  213.     int r, g, b;
  214.  
  215.     paletteram[offset] = data & 0x0f;
  216.  
  217.     r = paletteram[(offset & ~3) + 0];
  218.     g = paletteram[(offset & ~3) + 1];
  219.     b = paletteram[(offset & ~3) + 2];
  220.     palette_change_color(offset / 4, (r << 4) | r, (g << 4) | g, (b << 4) | b);
  221. }
  222.  
  223.  
  224.  
  225. /*************************************
  226.  *
  227.  *        Main screen refresh
  228.  *
  229.  *************************************/
  230.  
  231. void balsente_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  232. {
  233.     UINT8 palette_used[4];
  234.     int x, y, i;
  235.  
  236.     /* update the remaining scanlines */
  237.     screen_refresh_counter++;
  238.     update_palette();
  239.  
  240.     /* determine which palette banks were used */
  241.     palette_used[0] = palette_used[1] = palette_used[2] = palette_used[3] = 0;
  242.     for (i = 0; i < 240; i++)
  243.         palette_used[scanline_palette[i]] = 1;
  244.  
  245.     /* make sure color 1024 is white for our crosshair */
  246.     palette_change_color(1024, 0xff, 0xff, 0xff);
  247.  
  248.     /* set the used status of all the palette entries */
  249.     for (x = 0; x < 4; x++)
  250.         if (palette_used[x])
  251.             memset(&palette_used_colors[x * 256], PALETTE_COLOR_USED, 256);
  252.         else
  253.             memset(&palette_used_colors[x * 256], PALETTE_COLOR_UNUSED, 256);
  254.     palette_used_colors[1024] = balsente_shooter ? PALETTE_COLOR_USED : PALETTE_COLOR_UNUSED;
  255.  
  256.     /* recompute the palette, and mark all scanlines dirty if we need to redraw */
  257.     if (palette_recalc())
  258.         memset(scanline_dirty, 1, 256);
  259.  
  260.     /* do the core redraw */
  261.     if (bitmap->depth == 8)
  262.         update_screen_8(bitmap, full_refresh);
  263.     else
  264.         update_screen_16(bitmap, full_refresh);
  265.  
  266.     /* draw a crosshair */
  267.     if (balsente_shooter)
  268.     {
  269.         int beamx = balsente_shooter_x;
  270.         int beamy = balsente_shooter_y - 12;
  271.  
  272.         int xoffs = beamx - 3;
  273.         int yoffs = beamy - 3;
  274.  
  275.         for (y = -3; y <= 3; y++, yoffs++, xoffs++)
  276.         {
  277.             if (yoffs >= 0 && yoffs < 240 && beamx >= 0 && beamx < 256)
  278.             {
  279.                 plot_pixel(bitmap, beamx, yoffs, Machine->pens[1024]);
  280.                 scanline_dirty[yoffs] = 1;
  281.             }
  282.             if (xoffs >= 0 && xoffs < 256 && beamy >= 0 && beamy < 240)
  283.                 plot_pixel(bitmap, xoffs, beamy, Machine->pens[1024]);
  284.         }
  285.     }
  286. }
  287.  
  288.  
  289. /*************************************
  290.  *
  291.  *        Depth-specific refresh
  292.  *
  293.  *************************************/
  294.  
  295. #define ADJUST_FOR_ORIENTATION(orientation, bitmap, dst, x, y, xadv)    \
  296.     if (orientation)                                                    \
  297.     {                                                                    \
  298.         int dy = bitmap->line[1] - bitmap->line[0];                        \
  299.         int tx = x, ty = y, temp;                                        \
  300.         if (orientation & ORIENTATION_SWAP_XY)                            \
  301.         {                                                                \
  302.             temp = tx; tx = ty; ty = temp;                                \
  303.             xadv = dy / (bitmap->depth / 8);                            \
  304.         }                                                                \
  305.         if (orientation & ORIENTATION_FLIP_X)                            \
  306.         {                                                                \
  307.             tx = bitmap->width - 1 - tx;                                \
  308.             if (!(orientation & ORIENTATION_SWAP_XY)) xadv = -xadv;        \
  309.         }                                                                \
  310.         if (orientation & ORIENTATION_FLIP_Y)                            \
  311.         {                                                                \
  312.             ty = bitmap->height - 1 - ty;                                \
  313.             if ((orientation & ORIENTATION_SWAP_XY)) xadv = -xadv;        \
  314.         }                                                                \
  315.         /* can't lookup line because it may be negative! */                \
  316.         dst = (TYPE *)(bitmap->line[0] + dy * ty) + tx;                    \
  317.     }
  318.  
  319. #define INCLUDE_DRAW_CORE
  320.  
  321. #define DRAW_FUNC update_screen_8
  322. #define TYPE UINT8
  323. #include "balsente.c"
  324. #undef TYPE
  325. #undef DRAW_FUNC
  326.  
  327. #define DRAW_FUNC update_screen_16
  328. #define TYPE UINT16
  329. #include "balsente.c"
  330. #undef TYPE
  331. #undef DRAW_FUNC
  332.  
  333.  
  334. #else
  335.  
  336.  
  337. /*************************************
  338.  *
  339.  *        Core refresh routine
  340.  *
  341.  *************************************/
  342.  
  343. void DRAW_FUNC(struct osd_bitmap *bitmap, int full_refresh)
  344. {
  345.     int orientation = Machine->orientation;
  346.     int x, y, i;
  347.  
  348.     /* draw any dirty scanlines from the VRAM directly */
  349.     for (y = 0; y < 240; y++)
  350.     {
  351.         UINT16 *pens = &Machine->pens[scanline_palette[y] * 256];
  352.         if (scanline_dirty[y] || full_refresh)
  353.         {
  354.             UINT8 *src = &local_videoram[y * 256];
  355.             TYPE *dst = (TYPE *)bitmap->line[y];
  356.             int xadv = 1;
  357.  
  358.             /* adjust in case we're oddly oriented */
  359.             ADJUST_FOR_ORIENTATION(orientation, bitmap, dst, 0, y, xadv);
  360.  
  361.             /* redraw the scanline */
  362.             for (x = 0; x < 256; x++, dst += xadv)
  363.                 *dst = pens[*src++];
  364.             scanline_dirty[y] = 0;
  365.         }
  366.     }
  367.  
  368.     /* draw the sprite images */
  369.     for (i = 0; i < 40; i++)
  370.     {
  371.         UINT8 *sprite = spriteram + ((0xe0 + i * 4) & 0xff);
  372.         UINT8 *src;
  373.         int flags = sprite[0];
  374.         int image = sprite[1] | ((flags & 3) << 8);
  375.         int ypos = sprite[2] + 17;
  376.         int xpos = sprite[3];
  377.  
  378.         /* get a pointer to the source image */
  379.         src = &memory_region(REGION_GFX1)[64 * image];
  380.         if (flags & 0x80) src += 4 * 15;
  381.  
  382.         /* loop over y */
  383.         for (y = 0; y < 16; y++, ypos = (ypos + 1) & 255)
  384.         {
  385.             if (ypos >= 16 && ypos < 240)
  386.             {
  387.                 UINT16 *pens = &Machine->pens[scanline_palette[y] * 256];
  388.                 UINT8 *old = &local_videoram[ypos * 256 + xpos];
  389.                 TYPE *dst = &((TYPE *)bitmap->line[ypos])[xpos];
  390.                 int currx = xpos, xadv = 1;
  391.  
  392.                 /* adjust in case we're oddly oriented */
  393.                 ADJUST_FOR_ORIENTATION(orientation, bitmap, dst, xpos, ypos, xadv);
  394.  
  395.                 /* mark this scanline dirty */
  396.                 scanline_dirty[ypos] = 1;
  397.  
  398.                 /* standard case */
  399.                 if (!(flags & 0x40))
  400.                 {
  401.                     /* loop over x */
  402.                     for (x = 0; x < 4; x++, dst += xadv * 2, old += 2)
  403.                     {
  404.                         int ipixel = *src++;
  405.                         int left = ipixel & 0xf0;
  406.                         int right = (ipixel << 4) & 0xf0;
  407.                         int pen;
  408.  
  409.                         /* left pixel */
  410.                         if (left && currx >= 0 && currx < 256)
  411.                         {
  412.                             /* combine with the background */
  413.                             pen = left | old[0];
  414.                             dst[0] = pens[pen];
  415.                         }
  416.                         currx++;
  417.  
  418.                         /* right pixel */
  419.                         if (right && currx >= 0 && currx < 256)
  420.                         {
  421.                             /* combine with the background */
  422.                             pen = right | old[1];
  423.                             dst[xadv] = pens[pen];
  424.                         }
  425.                         currx++;
  426.                     }
  427.                 }
  428.  
  429.                 /* hflip case */
  430.                 else
  431.                 {
  432.                     src += 4;
  433.  
  434.                     /* loop over x */
  435.                     for (x = 0; x < 4; x++, dst += xadv * 2, old += 2)
  436.                     {
  437.                         int ipixel = *--src;
  438.                         int left = (ipixel << 4) & 0xf0;
  439.                         int right = ipixel & 0xf0;
  440.                         int pen;
  441.  
  442.                         /* left pixel */
  443.                         if (left && currx >= 0 && currx < 256)
  444.                         {
  445.                             /* combine with the background */
  446.                             pen = left | old[0];
  447.                             dst[0] = pens[pen];
  448.                         }
  449.                         currx++;
  450.  
  451.                         /* right pixel */
  452.                         if (right && currx >= 0 && currx < 256)
  453.                         {
  454.                             /* combine with the background */
  455.                             pen = right | old[1];
  456.                             dst[xadv] = pens[pen];
  457.                         }
  458.                         currx++;
  459.                     }
  460.                     src += 4;
  461.                 }
  462.             }
  463.             else
  464.                 src += 4;
  465.             if (flags & 0x80) src -= 2 * 4;
  466.         }
  467.     }
  468. }
  469.  
  470. #endif
  471.